/*

Copyright 2007 Renaun Erickson (http://renaun.com)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ignore
*/
package asfslib.services.familytree
{
import asfslib.FamilySearchService;
import asfslib.api.familytree.v1.SearchHit;
import asfslib.events.FamilySearchServiceEvent;
import asfslib.services.BaseService;

import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;

import mx.collections.ArrayCollection;

/**
 * Fired when a result is obtain from the respective service call.
 */
[Event(name="search", type="asfslib.events.FamilySearchServiceEvent")]
	
public class SearchService extends BaseService
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

	/**
	 * 	Constructor
	 */
	public function SearchService(service:FamilySearchService)
	{
		super(service);
		
		var type:String = FamilySearchService.FAMILY_TREE_SERVICES;
		var ver:String = FamilySearchService.FAMILY_TREE_VERSION_STRING;
		var name:String = FamilySearchService.SEARCH_SERVICE;		
		endpoint = service.familySearchURL + type + "/" + ver + "/" + name
	}	

    //--------------------------------------------------------------------------
    //
    //  Variables
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  startIndex
    //----------------------------------

    /**
     *  @private
     *  Storage for the startIndex property.
     */
    private var _startIndex:int;

    /**
     *  The startIndex property
     *
     *  @default 
     */
    public function get startIndex():int
    {
        return _startIndex;
    }

    /**
     *  @private
     */
    public function set startIndex(value:int):void
    {
        _startIndex = value;
    }


    //----------------------------------
    //  maxResults
    //----------------------------------

    /**
     *  @private
     *  Storage for the maxResults property.
     */
    private var _maxResults:int;

    /**
     *  The maxResults property
     *
     *  @default 
     */
    public function get maxResults():int
    {
        return _maxResults;
    }

    /**
     *  @private
     */
    public function set maxResults(value:int):void
    {
        _maxResults = value;
    }


    //----------------------------------
    //  name
    //----------------------------------

    /**
     *  @private
     *  Storage for the name property.
     */
    private var _name:String = "";

    /**
     *  The name property
     *
     *  @default ""
     */
    public function get name():String
    {
        return _name;
    }

    /**
     *  @private
     */
    public function set name(value:String):void
    {
        _name = value;
    }


    //----------------------------------
    //  givenName
    //----------------------------------

    /**
     *  @private
     *  Storage for the givenName property.
     */
    private var _givenName:String = "";

    /**
     *  The givenName property
     *
     *  @default ""
     */
    public function get givenName():String
    {
        return _givenName;
    }

    /**
     *  @private
     */
    public function set givenName(value:String):void
    {
        _givenName = value;
    }


    //----------------------------------
    //  familyName
    //----------------------------------

    /**
     *  @private
     *  Storage for the familyName property.
     */
    private var _familyName:String = "";

    /**
     *  The familyName property
     *
     *  @default ""
     */
    public function get familyName():String
    {
        return _familyName;
    }

    /**
     *  @private
     */
    public function set familyName(value:String):void
    {
        _familyName = value;
    }

    //----------------------------------
    //  birthDate
    //----------------------------------

    /**
     *  @private
     *  Storage for the birthDate property.
     */
    private var _birthDate:String;

    /**
     *  The birthDate property
     *
     *  @default ""
     */
    public function get birthDate():String
    {
        return _birthDate;
    }

    /**
     *  @private
     */
    public function set birthDate(value:String):void
    {
        _birthDate = value;
    }

    //----------------------------------
    //  returnOnlyHits
    //----------------------------------

    /**
     *  @private
     *  Storage for the returnOnlyHits property.
     */
    private var _returnOnlyHits:Boolean = true;

    /**
     *  The returnOnlyHits property
     *
     *  @default true
     */
    public function get returnOnlyHits():Boolean
    {
        return _returnOnlyHits;
    }

    /**
     *  @private
     */
    public function set returnOnlyHits(value:Boolean):void
    {
        _returnOnlyHits = value;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *	Search for people in the FamilySearch database.
     *  Default is to just search on the givenName, all other optional parameters
     *  have to be set before making the call.
     */ 
    public function search(name:String):void
    {
    	this.name = name;

		// TODO Build Query String off all parameters.
		var urlRequest:URLRequest = new URLRequest(endpoint);
		urlRequest.method = URLRequestMethod.GET;

        var variables:URLVariables = new URLVariables();
        variables.name = name;
        if (birthDate && birthDate != "")
        	variables.birthDate = birthDate;
        variables.sessionId = service.sessionID;
        urlRequest.data = variables;
 
		serviceLoader.load(urlRequest);
    }
    
    /**
     *	Override the completeHandler
     */
    override protected function completeHandler(event:Event):void
    {
    	var loader:URLLoader = event.target as URLLoader;
    	var resultXML:XML = XML(loader.data);

		if (checkFSAPIErrors(resultXML))
			return;
		
		var results:ArrayCollection = parseResults(resultXML);
		
		var serviceEvent:FamilySearchServiceEvent = new FamilySearchServiceEvent(
															FamilySearchServiceEvent.SEARCH,
															false,
															false,
															results);
		
		
		dispatchEvent(serviceEvent);
    }
    
    /**
     *	Parse the result XML and create the Objects
     */
    private function parseResults(resultXML:XML):ArrayCollection
    {
		if (resultXML.namespace("") != undefined) 
		{
		    default xml namespace = resultXML.namespace("");
		}    	
		
    	var searchHits:ArrayCollection = new ArrayCollection();
    	var hits:int = int.MAX_VALUE;
    	if (returnOnlyHits)
    		hits = int(resultXML.searches.@count);
    	var count:int = 0;
// CHG 20080102: chanced results.result to searches.search    	
    	for each(var resultNode:XML in resultXML.searches.search)
    	{
    		if (count < hits)
    			searchHits.addItem(SearchHit.parseXML(resultNode));
    		else
    			break;
    		count++;
    	}
    	
    	default xml namespace = new Namespace("");
    	return searchHits;
    }
}
}